package com.benzhu.shiro.realm;

import com.benzhu.shiro.dao.UserDao;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Component("realm")
public class CustomRealm extends AuthorizingRealm {

    @Resource
    private UserDao userDao;

    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        String username = (String) principals.getPrimaryPrincipal();
        //从缓存中拿到角色数据(没有设置缓存只能再查一次数据库)
        Set<String> roles = getRolesByUserName(username);
        //从缓存中拿到权限数据(没有设置缓存只能再查一次数据库)
        Set<String> permissions = getPermissionUserName(roles);
        //返回对象
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.setRoles(roles);
        authorizationInfo.setStringPermissions(permissions);
        return authorizationInfo;
    }

    private Set<String> getPermissionUserName(Set<String> roles) {
        Set<String> sets = new HashSet<>();
        for (String role : roles){
            List<String> permission = userDao.getPermissionByUserName(role);
            for (String permis:permission) {
                //这里输出可以看出运行了两次
                System.out.println(permis);
                sets.add(permis);
            }
        }
        return sets;
    }

    private Set<String> getRolesByUserName(String username) {
        List<String> roles = userDao.getRolesByUSerName(username);
        Set<String> sets = new HashSet<>(roles);
        return sets;
    }

    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //1.从主体传过来的认证信息中获取用户名
        String username = (String) token.getPrincipal();
        //2.通过用户名到数据库中获取凭证
        String password = getPasswordByUserName(username);
        if(password == null){
            return null;
        }
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username,password,"customRealm");
        //加盐验证
        authenticationInfo.setCredentialsSalt(ByteSource.Util.bytes("benzhu"));
        return authenticationInfo;

    }

    private String getPasswordByUserName(String username) {
        //模拟数据库查询
        return userDao.getUserPassWord(username);
    }

/*    public static void main(String[] args) {
        //计算加密结果的主方法 用来计算加密的密码结果 非必需
        Md5Hash md5Hash = new Md5Hash("123456","benzhu");
        System.out.println(md5Hash);
    }*/
}
